#ifndef _MATH_INTERPOL_H_
#define _MATH_INTERPOL_H_

#include "./math_define.h"

namespace Mathematics {
	//! namespace for interpolation
	/*!
		that's it
	*/
	namespace Interpolation{
		//! Linear.
		/*! 
			Linear Interpolation from 2 given values.
			
			\param a initial value
			\param b final value
			\param factor interpolation coeficient
			\return interpolated value. Next to 0 means result next to a. Next to 1 means result next to b.
			
			\code
			cout << Linear( 0, 10, 0.6 ) << endl	// 6
			cout << Linear( Point(1.0, 2.0), Point(5.0, -1.0), 0.2 ) << endl	// ( 1.8, 1.4 )
			\endcode
			
			\code
			Matrix1D mt1( 3 );
			Matrix1D mt2( 3 );
			
			for( usint i = 0; i < 3; ++i ){
				mt1[i] = i;
				mt2[i] = 10+i;
			}
			cout << Experimental( mt1, mt2, 0.6 ) << endl	// [ 6.0, 7.0, 8.0 ]
			\endcode
		*/
		template <class T>
			inline T Linear(const T &a, const T &b, const double &factor){
				return a*(1.0-factor) + b*factor;
			};
		
		//! Mixture.
		/*! 
			Alias - LinearInterpolation.
			
			\param a initial value
			\param b final value
			\param factor interpolation coeficient
			\return interpolated value. Next to 0 means result next to a. Next to 1 means result next to b.
			
			\sa inline T Linear(const T &a, const T &b, const double &factor);
			
		*/
		template <class T>
			inline T Mix(const T &a, const T &b, const double &factor){
				return Linear(a,b,factor);
			};
		
		//! Experimental.
		/*! 
			Experimental Interpolation from 2 given values.
			
			\param a initial value
			\param b final value
			\param factor interpolation coeficient
			\param exp power given to the factor
			\return interpolated value. Next to 0 means result next to a. Next to 1 means result next to b.
						The value is from the same type of a and b.
			
			\code
			cout << Experimental( 0, 10, 0.6, 1.0 ) << endl	// 6 (linear)
			cout << Experimental( 0.0, 10.0, 0.6 ) << endl	// 3.6 (square)
			cout << Experimental( 0, 10, 0.6, 3.0 ) << endl	// 2.16 (cubic)
			\endcode
			
			\code
			cout << Experimental( 0, 10, 0.6 ) << endl	// 3 (square - rounded)
			
			Matrix1D mt1( 3 );
			Matrix1D mt2( 3 );
			
			for( usint i = 0; i < 3; ++i ){
				mt1[i] = i;
				mt2[i] = 10+i;
			}
			cout << Experimental( mt1, mt2, 0.6 ) << endl	// [ 3.6, 4.6, 5.6 ]
			\endcode
		*/
		template <class T>
			inline T Experimental( const T &a, const T &b, const double &factor, const double &exp = 2.0 ){
				return a + ( b - a ) * pow( factor , exp );
			};
			
		//! function for testing interpolation definitions
		void InterpolTest();
	};
};

#endif
